package cz.data.domain.market.utils;

import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.JdbcNamedParameter;
import net.sf.jsqlparser.parser.SimpleNode;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.StatementVisitorAdapter;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectItemVisitorAdapter;
import net.sf.jsqlparser.statement.select.SelectVisitorAdapter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultipleStatementVisitorAdapter extends StatementVisitorAdapter {
    // 返回字段
    private final List<Map<String, String>> cols;
    // 查询入参字段
    private final List<String> vars;

    public MultipleStatementVisitorAdapter(List<Map<String, String>> cols, List<String> vars) {
        this.cols = cols;
        this.vars = vars;
    }

    @Override
    public void visit(Select select) {
        select.getSelectBody().accept(new SelectVisitorAdapter() {
            @Override
            public void visit(PlainSelect plainSelect) {
                // 存储表名
                Map<String, String> map = new HashMap<>();
                Table table = (Table) plainSelect.getFromItem();
                if (table.getAlias() != null) {
                    map.put(table.getName(), table.getAlias().getName());
                }
                for (Join join : plainSelect.getJoins()) {
                    Table table1 = (Table) join.getRightItem();
                    if (table1.getAlias() != null) {
                        map.put(table1.getName(), table1.getAlias().getName());
                    }
                }
                plainSelect.getSelectItems().forEach(selectItem -> {
                    selectItem.accept(new SelectItemVisitorAdapter() {
                        @Override
                        public void visit(SelectExpressionItem item) {
                            Map<String, String> m = new HashMap<>();
                            String tableName = "", columnName;
                            SimpleNode node = item.getExpression().getASTNode();
                            Object value = node.jjtGetValue();
                            if (value instanceof Column) {
                                Column column = (Column) value;
                                Table table = column.getTable();
                                if (table != null) {
                                    for (Map.Entry<String, String> entry : map.entrySet()) {
                                        if (table.getName().equals(entry.getValue())) {
                                            tableName = entry.getKey();
                                            break;
                                        }
                                    }
                                }
                                columnName = column.getColumnName();
                                if (item.getAlias() != null) {
                                    m.put("columnAliasName", item.getAlias().getName());
                                }
                            } else if (value instanceof Function) {
                                columnName = value.toString();
                            } else {
                                // 增加对select 'aaa' from table; 的支持
                                columnName = String.valueOf(value);
                                columnName = columnName.replace("'", "");
                                columnName = columnName.replace("\"", "");
                                columnName = columnName.replace("`", "");
                            }
                            columnName = columnName.replace("'", "");
                            columnName = columnName.replace("\"", "");
                            columnName = columnName.replace("`", "");
                            m.put("tableName", tableName);
                            m.put("columnName", columnName);
                            cols.add(m);
                        }
                    });
                });
                plainSelect.getWhere().accept(new ExpressionVisitorAdapter() {
                    @Override
                    public void visit(JdbcNamedParameter jdbcNamedParameter) {
                        vars.add(jdbcNamedParameter.getName());
                    }
                });
            }
        });
    }
}
